//
//  BACopy.m
//  BAClassUtil
//
//  Created by pdc on 2017/9/24.
//  Copyright © 2017年 RealsCloud. All rights reserved.
//

#import "BACopy.h"
#import <objc/runtime.h>
#import "BAMetaClassInfo.h"

@implementation BACopy
+(void )copy:(NSObject *)sourceObj to:(NSObject *)targetObj
{
    [[self class] copy:sourceObj to:targetObj ignore:nil];
}

+(void )copy:(NSObject *)sourceObj to:(NSObject *)targetObj ignore:(NSArray<NSString *> *)propertyNames
{
    NSAssert(sourceObj!=nil, @"source object can not nil");
    NSAssert(targetObj!=nil, @"target object can not nil");
    
    BAMetaClassInfo *metaSource = [BAMetaClassInfo MetaClassInfoWithClass:sourceObj.class];
    BAMetaClassInfo *metaTarget = [BAMetaClassInfo MetaClassInfoWithClass:targetObj.class];
    if (metaSource.allProperty.count == 0 || metaTarget.allProperty.count == 0)
    {
        return ;
    }
    //ignore private property
    NSArray<NSString *> *defaultIgnore = @[@"hash",@"superclass",@"description",@"debugDescription",@"observationInfo"];
    if (nil != propertyNames && propertyNames.count > 0)
    {
        defaultIgnore = [defaultIgnore arrayByAddingObjectsFromArray:propertyNames];
    }
    NSArray<BAPropertyInfo *> *mirrorPropertys = [[self class] findMirrorPropertys1:metaSource.allProperty propertys2:metaTarget.allProperty];
    [mirrorPropertys enumerateObjectsUsingBlock:^(BAPropertyInfo * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (![defaultIgnore containsObject:obj.name])
        {
            NSString *key = obj.name;
            SEL setter = NSSelectorFromString([NSString stringWithFormat:@"set%@%@:",[key substringToIndex:1].uppercaseString,[key substringFromIndex:1]]);
            SEL getter = NSSelectorFromString(key);
            //这个if要不要加有点纠结，不加的时候readonly属性也可以被赋值；加了，破坏readonly的限制性。所以最后没加上去
            if ([targetObj respondsToSelector:setter] && [targetObj respondsToSelector:getter])
            {
                id value = [sourceObj valueForKey:key];
                if (nil != value
                    && ![value isKindOfClass:[NSNull class]])
                {
                    //这里用的kvc，其实可以用obj_sendMessage，后面再完善
                    [targetObj setValue:value forKey:key];
                }
            }
        }
    }];
}

+(void )deepCopy:(NSObject *)sourceObj to:(NSObject *)targetObj
{
    [[self class] deepCopy:sourceObj to:targetObj ignore:nil];
}

+(void )deepCopy:(NSObject *)sourceObj to:(NSObject *)targetObj ignore:(NSArray<NSString *> *)propertyNames
{
    
}

+(NSArray<BAPropertyInfo *> *)findMirrorPropertys1:(NSArray<BAPropertyInfo *> *)propertys1 propertys2:(NSArray<BAPropertyInfo *> *)propertys2
{
    NSMutableArray<BAPropertyInfo *> *mirrorPropertyInfos = [NSMutableArray array];
    //这里直接用两个数组循环比较了，因为不会写算法去优化
    [propertys1 enumerateObjectsUsingBlock:^(BAPropertyInfo * _Nonnull obj1, NSUInteger idx1, BOOL * _Nonnull stop1) {
        [propertys2 enumerateObjectsUsingBlock:^(BAPropertyInfo * _Nonnull obj2, NSUInteger idx2, BOOL * _Nonnull stop2) {
            if ([obj1.name isEqualToString:obj2.name])
            {
                [mirrorPropertyInfos addObject:obj1];
                *stop2 = YES;
            }
        }];
    }];
    if (mirrorPropertyInfos.count == 0)
    {
        return nil;
    }
    return [mirrorPropertyInfos copy];
}
@end
